package com.situ.mall.function.stream;

import com.situ.mall.function.pojo.Banji;
import com.situ.mall.function.pojo.Student;
import org.junit.jupiter.api.Test;

import javax.xml.bind.SchemaOutputResolver;
import java.lang.reflect.Array;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class TTT {

    @Test
    public void test88() {
        List<Banji> banjis = getBanjis();
        List<Integer> list = new ArrayList<>();
        for (Banji banji : banjis) {
            List<Student> students = banji.getStudents();
            for (Student student : students) {
                if (student.getAge() > 18) {
                    list.add(student.getAge());
                }
            }
        }
        System.out.println(list);

        System.out.println("------------------");
        //flatMap 将流展开
        List<Integer> list1 = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .filter(student -> student.getAge() > 18)
                .map(student -> student.getAge())
                .collect(Collectors.toList());
        Set<Integer> set = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .filter(student -> student.getAge() > 18)
                .map(student -> student.getAge())
                .collect(Collectors.toSet());
        System.out.println(list1);
    }

    @Test
    public void test2() {
        List<Student> students = getStudents();
        Stream<Student> stream1 = students.stream();

        Map<String, String> map = new HashMap<>();
        map.put("cn", "中国");
        map.put("us", "美国");
        Stream<Map.Entry<String, String>> stream2 = map.entrySet().stream();

        Integer[] array = {1, 2, 3, 4};
        Stream<Integer> stream3 = Arrays.stream(array);
        Stream<Integer> stream4 = Stream.of(array);
    }


    @Test
    public void test21() {
        List<Student> students = getStudents();
        students.stream()
                .distinct()
                .filter(student -> student.getName().length() > 1)
                .forEach(student -> System.out.println(student));
    }

    @Test
    public void test22() {
        List<Student> students = getStudents();
        students.stream()
                .distinct()
                .map(student -> student.getName())
                .forEach(name -> System.out.println(name));
    }

    @Test
    public void test5() {
        List<Student> students = getStudents();
        students.stream()
                .distinct()
                .sorted()
                .forEach(student -> System.out.println(student));

        System.out.println("-------------");

        students.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge() - o1.getAge())
                .forEach(student -> System.out.println(student));
    }

    @Test
    public void test52() {
        List<Student> students = getStudents();
        students.stream()
                .distinct()
                .sorted()
                .skip(1)
                .forEach(student -> System.out.println(student));

        System.out.println("-------------");

        students.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge() - o1.getAge())
                .limit(2)
                .forEach(student -> System.out.println(student));
    }

    @Test
    public void test45() {
        List<Banji> banjis = getBanjis();
        banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .distinct()
                .map(student -> student.getName())
                .forEach(name -> System.out.println(name));
    }

    @Test
    public void test556() {
        List<Banji> banjis = getBanjis();
        long count = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .distinct()
                .count();
        System.out.println(count);
    }

    @Test
    public void test99() {
        List<Banji> banjis = getBanjis();
        Optional<Integer> max = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getAge())
                .max((age1, age2) -> age1 - age2);
        Optional<Integer> min = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getAge())
                .min((age1, age2) -> age1 - age2);
        System.out.println(max.get());
        System.out.println(min.get());
    }

    @Test
    public void test665() {
        //anyMatch 判断是否有年龄在18以上的学生
        List<Banji> banjis = getBanjis();
        boolean flag = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .anyMatch(student -> student.getAge() > 18);
        System.out.println(flag);

        //findAny 获取任意一个年龄大于18的学生，如果存在就输出他的名字
        Optional<Student> optionalStudent = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .filter(student -> student.getAge() > 18)
                .findAny();
        optionalStudent.ifPresent(student -> System.out.println(student));
    }

    @Test
    public void test991() {
        //可以将流中元素反复结合起来，得到一个值
        int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int sum = 0;
        for (int i : array) {
            sum += i;
        }
        System.out.println(sum);
        System.out.println("--------------");
        Arrays.stream(array).reduce(0, new IntBinaryOperator() {
            @Override
            public int applyAsInt(int left, int right) {
                return Integer.sum(left, right);
                //return left + right;
            }
        });
        int s = Arrays.stream(array).reduce(0, (left, right) -> left + right);

        //T reduce(T identity, BinaryOperator<T> accumulator);
        //计算1-10的和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer sum1 = list.stream()
                .reduce(0, new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer a, Integer b) {
                        return a + b;
                    }
                });
        Integer sum2 = list.stream().reduce(0, (a, b) -> a + b);

        Integer sum3 = list.stream().reduce(0, (a, b) -> Integer.sum(a, b));
        Integer sum4 = list.stream().reduce(0, Integer::sum);
        System.out.println(sum);
        System.out.println(sum1);
        System.out.println(sum2);
        System.out.println(sum3);

        //Optional<T> reduce(BinaryOperator<T> accumulator);
        //计算所有学生年龄总和
        List<Banji> banjis = getBanjis();
        Optional<Integer> sumOptional1 = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getAge())
                .reduce(new BinaryOperator<Integer>() {
                    @Override
                    public Integer apply(Integer a, Integer b) {
                        return a + b;
                    }
                });
        Optional<Integer> sumOptional2 = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getAge())
                .reduce((a, b) -> a + b);
        System.out.println(sumOptional1.get());
        System.out.println(sumOptional2.get());

    }

    //获取一个存放所有学生名字的List和Set集合。
    @Test
    public void test451() {
        List<Banji> banjis = getBanjis();
        List<String> nameList = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getName())
                .collect(Collectors.toList());
        System.out.println(nameList);

        Set<String> nameSet = banjis.stream()
                .flatMap(banji -> banji.getStudents().stream())
                .map(student -> student.getName())
                .collect(Collectors.toSet());
        System.out.println(nameSet);


    }

    //获取一个Map集合，map的key为班级名，value为List<Student
    @Test
    public void test7878() {
        List<Banji> banjis = getBanjis();
        //Map<String, List<Student>> map;
        Map<String, List<Student>> map1 = banjis.stream()
                .distinct()
                .collect(Collectors.toMap(new Function<Banji, String>() {
                    @Override
                    public String apply(Banji banji) {
                        return banji.getName();
                    }
                }, new Function<Banji, List<Student>>() {
                    @Override
                    public List<Student> apply(Banji banji) {
                        return banji.getStudents();
                    }
                }));
        Map<String, List<Student>> map2 = banjis.stream()
                .distinct()
                .collect(Collectors.toMap(banji -> banji.getName(), banji -> banji.getStudents()));
    }


    public List<Student> getStudents() {
        Student student1 = new Student(1, "张三", 23);
        Student student2 = new Student(2, "李", 33);
        Student student3 = new Student(3, "王五", 16);
        List<Student> list = new ArrayList<>();
        list.add(student1);
        list.add(student2);
        list.add(student3);
        list.add(student3);
        return list;
    }



    public List<Banji> getBanjis() {
        Banji banji1 = new Banji(1, "Java2307", null);
        Banji banji2 = new Banji(2, "UI2307", null);
        Banji banji3 = new Banji(3, "H52307", null);

        //学生列表
        List<Student> students1 = new ArrayList<>();
        List<Student> students2 = new ArrayList<>();
        List<Student> students3 = new ArrayList<>();

        students1.add(new Student(1, "张三1", 23));
        students1.add(new Student(2, "张三2", 33));
        students1.add(new Student(3, "张三3", 16));
        students1.add(new Student(3, "张三3", 16));

        students2.add(new Student(4, "李四1", 123));
        students2.add(new Student(5, "李四2", 33));
        students2.add(new Student(6, "李四3", 16));

        students3.add(new Student(7, "王五1", 23));
        students3.add(new Student(8, "王五2", 33));
        students3.add(new Student(9, "王五3", 16));

        banji1.setStudents(students1);
        banji2.setStudents(students2);
        banji3.setStudents(students3);

        List<Banji> banjis = Arrays.asList(banji1, banji2, banji3);
        return banjis;
    }
}
